package com.itvita.code.generator.engine;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.itvita.code.generator.config.JdbcTemplateConfig;
import com.itvita.code.generator.constant.TemplateConstVal;
import com.itvita.code.generator.entity.ColumnInfo;
import com.itvita.code.generator.entity.TableInfo;
import com.itvita.code.generator.entity.model.CreateInfo;
import com.itvita.code.generator.service.GeneratorService;
import com.itvita.code.generator.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;

/**
 * Time: 2021/1/22 9:19 上午
 * author: liu.q [916000612@qq.com]
 * des: 模板引擎抽象类
 */
@Slf4j
public abstract class AbstractTemplateEngine {
    /*基础参数信息*/
    private CreateInfo createDto;
    /*service*/
    private GeneratorService generatorService;

    /*模板引擎初始化*/
    public AbstractTemplateEngine init(CreateInfo createDto) {
        this.createDto = createDto;
        /*service*/
        JdbcTemplate jdbcTemplate = JdbcTemplateConfig.getJdbcTemplate(createDto.getDataSource());
        generatorService = new GeneratorService(jdbcTemplate);
        return this;
    }

    /**
     * 输出
     */
    public AbstractTemplateEngine exec() {
        /*要生成的表*/
        List<String> tables = createDto.getTables();
        for (String tableName : tables) {
            /*总配置*/
            TemplateConfig templateConfig = new TemplateConfig();
            /*表名*/
            templateConfig.setTableName(tableName);
            /*包名*/
            templateConfig.setPackageName(createDto.getPackageName());
            /*列信息*/
            templateConfig.setColumnInfoList(columnInfos(tableName));

//            String sub = TemplateConstVal.TEMPLATE_ENTITY_JAVA_NAME;
//            sub = sub.substring(0, sub.indexOf("."));

            /*entity名大写*/
            templateConfig.setUpperEntityName(StrUtil.upperFirst(CommonUtil.line2Hump(tableName)));
            /*entity名小写*/
            templateConfig.setLowerEntityName(StrUtil.lowerFirst(CommonUtil.line2Hump(tableName)));
            /*日期*/
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
            templateConfig.setDateTime(dateTimeFormatter.format(LocalDateTime.now()));
            /*开发者*/
            templateConfig.setAuthor(createDto.getAuthor());
            /*备注*/
            TableInfo tableInfo = generatorService.getOneTable(createDto.getDataSource().getDatabase(), tableName);
            templateConfig.setDesc(tableInfo.getTableComment());
            /*请求映射地址*/
            String contextPath = createDto.getContextPath();
            String s = contextPath.substring(contextPath.length() - 1);
            if (s.equals("/")) {
                templateConfig.setRequestMapping(contextPath + tableName.toLowerCase(Locale.CHINA).replaceAll("_", "/"));
            } else {
                templateConfig.setRequestMapping(contextPath + "/" + tableName.toLowerCase(Locale.CHINA).replaceAll("_", "/"));
            }
            /*权限标识*/
            templateConfig.setAuthSite(tableName.toLowerCase(Locale.CHINA));

            /*模板配置信息*/
            create(templateConfig);
        }
        return this;
    }

    private void create(TemplateConfig templateConfig) {
        String PackagePath = templateConfig.getPackageName().replaceAll("\\.", Matcher.quoteReplacement(File.separator));

        System.out.println(PackagePath);
        /*生成entity*/
        build(templateConfig,
                true,
                createDto.getProjectPath() + TemplateConstVal.TEMPLATE_JAVA_STATICPATH + File.separator + PackagePath + File.separator + "model" + File.separator + "po" + File.separator + templateConfig.getUpperEntityName() + ".java",
                TemplateConstVal.TEMPLATE_ENTITY_JAVA_NAME_PATH);

        build(templateConfig,
                false,
                createDto.getProjectPath() + TemplateConstVal.TEMPLATE_JAVA_STATICPATH + File.separator + PackagePath + File.separator + "model" + File.separator + "dto" + File.separator + templateConfig.getUpperEntityName() + "Dto.java",
                TemplateConstVal.TEMPLATE_ENTITYDTO_JAVA_NAME_PATH);

        /*生成Mapper*/
        build(templateConfig,
                false,
                createDto.getProjectPath() + TemplateConstVal.TEMPLATE_JAVA_STATICPATH + File.separator + PackagePath + File.separator + "mapper" + File.separator + templateConfig.getUpperEntityName() + "Mapper.java",
                TemplateConstVal.TEMPLATE_MAPPER_NAME_PATH);

        /*生成mapping*/
        build(templateConfig,
                false,
                createDto.getProjectPath() + TemplateConstVal.TEMPLATE_XML_STATICPATH + File.separator + "mapping" + File.separator + templateConfig.getUpperEntityName() + "Mapping.xml",
                TemplateConstVal.TEMPLATE_XML_NAME_PATH);
        /*生成service*/
        build(templateConfig,
                false,
                createDto.getProjectPath() + TemplateConstVal.TEMPLATE_JAVA_STATICPATH + File.separator + PackagePath + File.separator + "service" + File.separator + templateConfig.getUpperEntityName() + "Service.java",
                TemplateConstVal.TEMPLATE_SERVICE_NAME_PATH);
        /*生成ServiceImpl*/
        build(templateConfig,
                false,
                createDto.getProjectPath() + TemplateConstVal.TEMPLATE_JAVA_STATICPATH + File.separator + PackagePath + File.separator + "service" + File.separator + "impl" + File.separator + templateConfig.getUpperEntityName() + "ServiceImpl.java",
                TemplateConstVal.TEMPLATE_SERVICE_IMPL_NAME_PATH);
        /*生成Controller*/
        build(templateConfig,
                false,
                createDto.getProjectPath() + TemplateConstVal.TEMPLATE_JAVA_STATICPATH + File.separator + PackagePath + File.separator + "controller" + File.separator + templateConfig.getUpperEntityName() + "Controller.java",
                TemplateConstVal.TEMPLATE_CONTROLLER_NAME_PATH);
    }

    private void build(TemplateConfig templateConfig, Boolean isCover, String outputFile, String templatePath) {
        if (!isCover) {
            /*如果文件存在，跳过*/
            File file = new File(outputFile);
            if (file.exists()) {
                log.debug("已存在，不覆盖：{}", outputFile);
                return;
            }
        }
        writer(templateConfig, outputFile, templatePath);
    }

    /*查询列信息*/
    private List<ColumnInfo> columnInfos(String tableName) {
        /*列信息*/
        List<ColumnInfo> list = generatorService.getColumnInfo(tableName);
        /*忽略字段*/
        List<String> ignore = new ArrayList<String>() {{
            add("created_by");
            add("created_name");
            add("created_time");
            add("updated_by");
            add("updated_name");
            add("updated_time");
        }};
        List<ColumnInfo> result = new ArrayList<>();
        list.forEach(item -> {
            if (!ignore.contains(item.getColumnName())) {
                result.add(item);
            }
        });
        list.clear();
        return result;
    }

    /*生成模板*/
    public abstract void writer(TemplateConfig templateConfig, String outputFile, String templatePath);


    public static void main(String[] args) {


        String s = "//ain//jaa//main//";
        System.out.println(s.replaceAll("//", File.separator));
    }
}
